
package com.e885.webservice;

import java.net.MalformedURLException;
import java.util.Collection;
import java.util.HashMap;

import javax.xml.namespace.QName;

import org.codehaus.xfire.XFireRuntimeException;
import org.codehaus.xfire.aegis.AegisBindingProvider;
import org.codehaus.xfire.annotations.AnnotationServiceFactory;
import org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.jaxb2.JaxbTypeRegistry;
import org.codehaus.xfire.service.Endpoint;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.transport.TransportManager;

/**
 * 連結 webservice 的 util
 * <br>
 * @author Eric.Kao(gau168.gau@msa.hinet.net)
 * @version 1.0
 * @company E885 Group
 * @copyright Copyright (c) 2001-2008
 */
public class WebServiceClient
{
	private static XFireProxyFactory proxyFactory = new XFireProxyFactory();

	private String xfireLocal = "xfire.local://";

	private HashMap endpoints = new HashMap();

	private Service service;

	private QName soapQName = new QName( "http://tempuri.org/", "Soap" );

	private QName endpointQName = new QName( "http://tempuri.org/", "SoapEndpoint" );

	private QName bindingQName = new QName( "http://tempuri.org/", "SoapBinding" );

	public WebServiceClient( String url, String soapName, Class theClass )
	{
		if( url == null || url.trim().length() == 0 )
			throw new IllegalArgumentException( "url is null" );

		if( soapName == null || soapName.trim().length() == 0 )
			throw new IllegalArgumentException( "soap Name is null" );

		if( theClass == null )
			throw new IllegalArgumentException( "theClass is null" );

		xfireLocal += soapName;

		create( theClass );

		endpoints.put( endpointQName, service.addEndpoint( endpointQName, bindingQName, xfireLocal ) );

		endpoints.put( soapQName, service.addEndpoint( soapQName, soapQName, url ) );
	}

	public Object getEndpoint( Endpoint endpoint )
	{
		try
		{
			return proxyFactory.create( ( endpoint ).getBinding(), ( endpoint ).getUrl() );
		}
		catch( MalformedURLException e )
		{
			throw new XFireRuntimeException( "Invalid URL", e );
		}
	}

	public Object getEndpoint( QName name )
	{
		Endpoint endpoint = ( ( Endpoint )endpoints.get( ( name ) ) );
		if( ( endpoint ) == null )
		{
			throw new IllegalStateException( "No such endpoint!" );
		}
		return getEndpoint( ( endpoint ) );
	}

	public Collection getEndpoints()
	{
		return endpoints.values();
	}

	public Object getSoap()
	{
		return getEndpoint( soapQName );
	}

	private void create( Class theClass )
	{
		TransportManager tm = ( org.codehaus.xfire.XFireFactory.newInstance().getXFire().getTransportManager() );

		HashMap props = new HashMap();

		props.put( "annotations.allow.interface", new Boolean( true ) );

		AegisBindingProvider provider = new AegisBindingProvider( new JaxbTypeRegistry() );

		AnnotationServiceFactory asf = new AnnotationServiceFactory( new Jsr181WebAnnotations(), tm, provider );

		asf.setBindingCreationEnabled( false );

		service = asf.create( theClass, props );

		asf.createSoap11Binding( service, bindingQName, "urn:xfire:transport:local" );
		asf.createSoap11Binding( service, soapQName, "http://schemas.xmlsoap.org/soap/http" );
	}
}
